package main

import "fmt"

func dummy(b int) int {
  // 声明一个c赋值进入参数并返回
  var c int
  c= b

  return c
}

func void() {}

/*
  变量逃逸的解析
  在使用 Go 语言进行编程时，Go 语言的设计者不希望开发者将精力放在内存应该分配在栈还是堆上的问题。
    编译器会自动帮助开发者完成这个纠结的选择。
  编译器觉得变量应该分配在堆和栈上的原则是：
    1. 变量是否被取地址。
    2. 变量是否发生逃逸。
*/
func main() {

    // 声明a变量并打印
    var a int
    // 调用void()函数
    void()
    // 打印a变量的值和dummy()函数返回
    fmt.Println(a, dummy(0))
}

/*
  运行 go run -gcflags "-m -l" demo51.go

  运行结果如下：
  # command-line-arguments
  ./main.go:29:13: a escapes to heap
  ./main.go:29:22: dummy(0) escapes to heap
  ./main.go:29:13: main ... argument does not escape
  0 0

  上面例子中变量 c 是整型，其值通过 dummy() 的返回值“逃出”了 dummy() 函数。
  c 变量值被复制并作为 dummy() 函数返回值返回，即使 c 变量在 dummy() 函数中分配的内存被释放，也不会影响 main() 中使用 dummy() 返回的值。c 变量使用栈分配不会影响结果。
*/
